package com.dzsw.dp.singleton;

/**
 * 双重检查锁
 *
 * 1. volatile 关键词：避免JVM的指令重排。
 * 2. synchronized 关键词：避免并发 new 对象，导致对象被覆盖。
 * 3. singleton == null 外层校验：单例对象创建出来后就不需要进入synchronized的锁逻辑了，提高读取效率。
 * 4. singleton == null 内层校验：避免进入synchronized关键词后对象的重复创建。
 *
 * 双重检查锁的问题：使用volatile关键字能保证执行顺序，但是在一定程度上会影响执行效率。
 */
public class DoubleCheckedSingleton {

    private static volatile DoubleCheckedSingleton instance;

    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                    return instance;
                }
            }
        }
        return instance;
    }

    public void doSomething() {
        System.out.println("double checked do something");
    }
}
